package com.persagy.service.quartz.impl;

import java.util.List;
import java.util.UUID;

import javax.annotation.Resource;

import org.quartz.Job;
import org.quartz.JobDetail;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.persagy.core.mvc.dao.CoreDao;
import com.persagy.core.quartz.ScheduleFactory;
import com.persagy.ems.constant.quartz.QuartzConstant;
import com.persagy.ems.pojo.quartz.JobErrorLog;
import com.persagy.ems.pojo.quartz.ScheduleJob;
import com.persagy.service.quartz.ScheduleJobService;

/**
 * quartz定时任务
 * 
 * @author Administrator
 *
 */
@Service("ScheduleJobService")
public class ScheduleJobServiceImpl implements ScheduleJobService {

	@Resource(name = "quartzDao")
	private CoreDao quartzDao;

	@Resource
	private ScheduleFactory scheduleFactory;
	
	@Override
	public List<ScheduleJob> getJobList(ScheduleJob job) throws Exception {
		List<ScheduleJob> list = quartzDao.query(job);
		if (list != null && list.size() > 0) {
			for (ScheduleJob temp : list) {
				temp.setJobCurrentStatus(scheduleFactory.getJobStatus(temp));
			}
		}
		return list;
	}

	@Override
	public synchronized int insertJob(ScheduleJob job) throws Exception {
		if(isJobExists(job)){
			throw new Exception("The jobName already existed, please check jobName!");
		}
		job.setJobId(UUID.randomUUID().toString());
		job.setJobStatus(QuartzConstant.JobStatus.NOT_START);
		return quartzDao.save(job);
	}

	@Override
	public synchronized int deleteJob(ScheduleJob job) throws Exception  {
		if (job == null || job.getJobName() == null) {
			throw new Exception("jobName can not be null!");
		}
		if (job.getJobGroup() == null) {
			throw new Exception("jobGroup can not be null!");
		}
		scheduleFactory.deleteJob(job);
		return quartzDao.remove(job);
	}

	@Override
	public synchronized int updateJob(ScheduleJob objectCriteria, ScheduleJob objectUpdate) throws Exception {
		scheduleFactory.updateJob(objectUpdate);
		return quartzDao.update(objectCriteria, objectUpdate);
	}

	@SuppressWarnings("unchecked")
	@Override
	public synchronized void startJob(ScheduleJob job) throws Exception {
		job.setJobStatus(QuartzConstant.JobStatus.NOT_START);
		List<ScheduleJob> result = quartzDao.query(job);
		if (result != null && result.size() > 0) {
			for (ScheduleJob jobParams : result) {
				scheduleFactory.registerJob(jobParams, (Class<? extends Job>) Class.forName(jobParams.getJobClassName()));
				ScheduleJob jobUpdate = new ScheduleJob();
				BeanUtils.copyProperties(jobParams, jobUpdate);
				jobUpdate.setJobStatus(QuartzConstant.JobStatus.START);
				quartzDao.update(jobParams, jobUpdate);
			}
		}
	}
	
	@Override
	public List<ScheduleJob> getScheduleJobs() throws Exception {
		List<ScheduleJob> list = scheduleFactory.getScheduleJobs();
		if (list != null) {
			for (ScheduleJob job : list) {
				ScheduleJob temp = quartzDao.query(job).get(0);
				job.setDesc(temp.getDesc());
				job.setJobClassName(temp.getJobClassName());
				job.setJobId(temp.getJobId());
				job.setJobParams(temp.getJobParams());
				job.setJobStatus(temp.getJobStatus());
			}
		}
		return list;
	}

	@Override
	public List<ScheduleJob> getRunningJobs() throws Exception {
		List<ScheduleJob> list = scheduleFactory.getRunningJobs();
		if (list != null) {
			for (ScheduleJob job : list) {
				ScheduleJob temp = quartzDao.query(job).get(0);
				job.setDesc(temp.getDesc());
				job.setJobClassName(temp.getJobClassName());
				job.setJobId(temp.getJobId());
				job.setJobParams(temp.getJobParams());
				job.setJobStatus(temp.getJobStatus());
			}
		}
		return list;
	}

	@Override
	public synchronized void pauseJob(ScheduleJob job) throws Exception {
		if (job == null || job.getJobName() == null) {
			throw new Exception("jobName can not be null!");
		}
		if (job.getJobGroup() == null) {
			throw new Exception("jobGroup can not be null!");
		}
		if (isJobRegister(job)) {
			ScheduleJob jobUpdate = new ScheduleJob();
			BeanUtils.copyProperties(job, jobUpdate);
			scheduleFactory.pauseJob(job);
			quartzDao.update(job, jobUpdate);
		} else {
			throw new Exception("该任务未注册!");
		}
	}

	@Override
	public synchronized void resumeJob(ScheduleJob job) throws Exception {
		if (job == null || job.getJobName() == null) {
			throw new Exception("jobName can not be null!");
		}
		if (job.getJobGroup() == null) {
			throw new Exception("jobGroup can not be null!");
		}
		if (isJobRegister(job)) {
			ScheduleJob jobUpdate = new ScheduleJob();
			BeanUtils.copyProperties(job, jobUpdate);
			scheduleFactory.resumeJob(job);
			quartzDao.update(job, jobUpdate);
		} else {
			throw new Exception("该任务未注册!");
		}
				
	}

	@Override
	public synchronized void triggerJob(ScheduleJob job) throws Exception {
		if (job == null || job.getJobName() == null) {
			throw new Exception("jobName can not be null!");
		}
		if (job.getJobGroup() == null) {
			throw new Exception("jobGroup can not be null!");
		}
		/*List<ScheduleJob> list = getJobList(job);
		if(CollectionUtils.isNotEmpty(list)){
			if (QuartzConstant.JobStatus.START.equals(list.get(0).getJobStatus())) {
				scheduleFactory.triggerJob(job);
			} else {
				throw new Exception("该任务未注册!");
			}
		}*/
		if (isJobRegister(job)) {
			scheduleFactory.triggerJob(job);
		} else {
			throw new Exception("该任务未注册!");
		}
	}

	@Override
	public void insertErrorLog(JobErrorLog error) {
		try {
			quartzDao.save(error);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	@Override
	public synchronized boolean isJobExists(ScheduleJob job) throws Exception{
		if (job == null || job.getJobName() == null) {
			throw new Exception("jobName can not be null!");
		}
		if (job.getJobGroup() == null) {
			throw new Exception("jobGroup can not be null!");
		}
		ScheduleJob query = new ScheduleJob();
		query.setJobName(job.getJobName());
		query.setJobGroup(job.getJobGroup());
		List<ScheduleJob> list = quartzDao.query(query);
		if (list != null && list.size() > 0) {
			return true;
		}
		return false;
	}
	
	@Override
    public synchronized boolean isJobRegister(ScheduleJob job) throws Exception {
    	if (job == null || job.getJobName() == null) {
			throw new Exception("jobName can not be null!");
		}
		if (job.getJobGroup() == null) {
			throw new Exception("jobGroup can not be null!");
		}
        JobDetail jobDetail = scheduleFactory.getJobDetail(job.getJobName(), job.getJobGroup());
        if (jobDetail == null) {
            return false;
        }
        return true;
    }
	
}
